/**
**************************************************************************************
*Founder Effect                                                                      *
*Copyright (C) 2006-2007, 5d Studios (www.5d-Studios.com)                            *
*                                                                                    *
*This library is free software; you can redistribute it and/or                       *
*modify it under the terms of the GNU Lesser General Public                          *
*License as published by the Free Software Foundation; either                        *
*version 2.1 of the License, or (at your option) any later version.                  *
*                                                                                    *
*This library is distributed in the hope that it will be useful,                     *
*but WITHOUT ANY WARRANTY; without even the implied warranty of                      *
*MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU                   *
*Lesser General Public License for more details.                                     *
*                                                                                    *
*You should have received a copy of the GNU Lesser General Public                    *
*License along with this library; if not, write to the Free Software                 *
*Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA      *
**************************************************************************************
*/
#pragma once

#include <string>
#include <map>
#include <vector>

#include "../shared/geom.h"
#include "../EventManager.h"

#include "CollisionManager.h"

template<class T>
class QuadTree;
class Scene;
class ICamera;
class IEntity;
class IWeapon;
class Player;
/**
==========================
Manage all the entities of the world
Tis' a Singleton
==========================
*/
class EntityManager
{
public:
    /** Only allow one instance of the Entity Manager */
    static EntityManager* GetInstance() { return instance; }

    /** Update each entity */
    void Update(float dt, ICamera* cam);

    /** Delete the Player */
    void DeletePlayer();
    /** Deletes all the entities */
    void DeleteAllEntities();
    /** Remove the entity without deleting it */
    void RemoveWithoutDeleting(IEntity* ent);

    /** Register the entity */
    void RegisterEntity( IEntity* ent, const std::string &name );
    /** Place the Entity */
    void PutInWorld( IEntity* ent );

    /** Get the Player */
    Player*   GetPlayer();

    /** Find Entity by Name */
    IEntity* Find( const std::string &name );
    /** Find Entity by id */
    IEntity* Find( int id );
    /** Return a list of all entities in a region */
    type_EntityMap FindInRegion( const Rect &region );
    /** 
        Return a list of all entities that lie on the line
      */
    type_EntityMap FindInLine( const Vector2f &start, const Vector2f &end ); 

    /** How many entities are active */
    size_t Count() { return m_entities.size(); };

    /** HACK--How to register the Map with entities?
        Reference: Currently I register the scene
        when we load a new Scene, look at InGameStateView::LoadScene()
        with the EntityManager, this is horrible and NEEDS fixing.
      */
    void    SetScene(Scene* scene);
    Scene* GetScene() { return m_scene; };
    /** Retrieve a Quadtree of Entities on the map */
    QuadTree<IEntity*>* GetEntityQuadTree() { return m_entityQuadTree; };
private:
    EntityManager(void);
    /** Add the entity to the map */
    void AddEntity( IEntity* ent);
    /** Remove the entity entirely */
    type_EntityList::iterator RemoveEntity(IEntity* ent);
    /** Prune the entity List */
    void CleanDeadEntities();

    // list of entities
    type_EntityList m_entities;

    // our instance
    static EntityManager *instance;
    // ids
    static unsigned int m_idcounter;

    // Get the player
    Player*     m_player;

    // it hurts me to write this
    // the current scene
    Scene*      m_scene;

    // quick list to all entities in the world
    QuadTree<IEntity*> *m_entityQuadTree;

    CollisionManager    m_collisionDetection;  // test collisions
public:
    virtual ~EntityManager(void);
};


/**
 * We Added/Removed this entity to the world,
 * so let anybody who cares know about it.
 */
struct EntityAdditionData : public IEventData
{
	EntityAdditionData( IEntity* ent ) : m_entity(ent) {};
	IEntity* m_entity;
	IEventData* Copy() { return new EntityAdditionData( m_entity ); };
    virtual ~EntityAdditionData() { };
};